﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameNode
{
    class SpiralNode : ConsoleNode
    {
        protected Direction move = Direction.OnStart;
        private int height = 0;
        private int wildth = 0;
        private int counter = 0;
        private int v = 0;

        public SpiralNode(int positionX, int positionY, char nodeSymbol, ConsoleColor color)
            : base(positionX, positionY,  nodeSymbol, color)
        {

        }

        protected bool IsOnTop(Func<int, int, Position> position)
        {
            if (position(X, Y - 1) == Position.Border)
                return true;
            return false;
        }
        protected bool IsOnLeftBorder(Func<int, int, Position> position)
        {
            if (position(X - 1, Y) == Position.Border)
                return true;
            return false;
        }
        protected bool IsOnDown(Func<int, int, Position> position)
        {
            if (position(X, Y + 1) == Position.Border)
                return true;
            return false;
        }
        protected bool IsOnRightBorder(Func<int, int, Position> position)
        {
            if (position(X + 1, Y) == Position.Border)
                return true;
            return false;
        }
        protected void MoveOnStart(Func<int, int, Position> position)
        {
            if ((!IsOnTop(position) || !IsOnLeftBorder(position)) && (move == Direction.OnStart))
            {
                if (position(X, Y - 1) == Position.Free)
                {
                    MoveUp();
                }
                if (position(X - 1, Y) == Position.Free)
                {
                    MoveLeft();
                }
            }
        }

        public override void Move(Func<int, int, Position> position)
        {
            MoveOnStart(position);
            if ((IsOnTop(position) && IsOnLeftBorder(position)) && (move == Direction.OnStart))
            {
                move = Direction.Down;
            }
            if (!IsOnDown(position) && (wildth == 0) && (move == Direction.Down))
            {
                if (position(X, Y + 1) == Position.Free)
                {
                    MoveDown();
                    v++;
                }
            }
            else if (IsOnDown(position) && (wildth == 0) && (move == Direction.Down))
            {
                move = Direction.Right;
            }
            if (!IsOnRightBorder(position) && (height == 0) && (move == Direction.Right))
            {
                if (position(X + 1, Y) == Position.Free)
                {
                    MoveRight();
                    wildth++;
                }
            }
            else if (IsOnRightBorder(position) && (height == 0) && (move == Direction.Right))
            {
                move = Direction.Up;
                height = v;
                v = 0;
            }

            if ((v < (height - counter) && !IsOnTop(position)) && (move == Direction.Up))
            {
                if (position(X, Y - 1) == Position.Free)
                {
                    MoveUp();
                    v++;
                }
            }
            else if ((v == (height - counter) && IsOnTop(position)) && (move == Direction.Up))
            {
                move = Direction.Left;
                v = 0;
            }
            if ((v < (wildth - counter) && !IsOnLeftBorder(position)) && (move == Direction.Left))
            {
                if (position(X - 1, Y) == Position.Free)
                {
                    MoveLeft();
                    v++;
                }
            }
            else if ((v == (wildth - counter) && IsOnLeftBorder(position)) && (move == Direction.Left))
            {
                if (position(X + 1, Y) == Position.Free)
                {
                    move = Direction.Down;
                    counter = counter + 1;
                    v = 0;
                    MoveRight();
                }
            }

            if ((v < (height - counter) && !IsOnDown(position)) && (move == Direction.Down))
            {
                if (position(X, Y + 1) == Position.Free)
                {
                    MoveDown();
                    v++;
                }
            }
            else if ((v == (height - counter) && !IsOnDown(position)) && (move == Direction.Down))
            {
                move = Direction.Right;
                v = 0;
            }
            if ((v < (wildth - (counter + 1)) && !IsOnRightBorder(position)) && (move == Direction.Right))
            {
                if (position(X + 1, Y) == Position.Free)
                {
                    MoveRight();
                    v++;
                }
            }
            else if ((v == (wildth - (counter + 1)) && !IsOnRightBorder(position)) && (move == Direction.Right))
            {
                move = Direction.Up;
                v = 0;
            }
        }
    }

    enum Direction
    {
        Up,
        Down,
        Left,
        Right,
        OnStart
    }
}
